package Q2;

import org.junit.Before;
import org.junit.Test;
import utils.FileUtils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
import java.util.List;

/**
 * 通过 Jpa 测试学生表的 CRUD
 *
 * @author chisheng
 * @since 2021-10-25
 */
public class JpaDemo {

    /**
     * 持久单元的实体管理器工厂
     */
    private EntityManagerFactory factory;

    /**
     * 测试初始化，主要完成 EntityManagerFactory 的赋值
     */
    @Before
    public void initialize() {
        factory = JpaConfig.getEntityManagerFactory();
    }

    /**
     * 测试插入一个学生到学生表中
     * 1) 通过 createEntityManager() 方法获取一个 EntityManager 对象
     * 2) 构造一个需要插入到数据库中的学生对象
     * 3) 通过 getTransaction() 获取 EntityTransaction 对象控制事务
     * 4) 通过 begin() 方法开启事务
     * 5) 通过 persist(Object object) 持久化学生对象
     * 6) 通过 commit() 提交事务
     * 7) 通过 close() 关闭 EntityManager
     */
    @Test
    public void testInsert() throws IOException {
        /* 获取一个 EntityManager 对象 */
        EntityManager manager = factory.createEntityManager();
        /* 构造一个需要插入到数据库中的学生对象 */
        byte[] photo = FileUtils.getFileBytes(FileUtils.getClasspathFile("photo.jpg"));
        JpaStudent insertedJpaStudent = new JpaStudent(
                10, "201901", "王五", 18, Date.valueOf("2000-07-05"), photo
        );
        /* 获取 EntityTransaction 对象控制事务 */
        EntityTransaction transaction = manager.getTransaction();
        /* 开启事务 */
        transaction.begin();
        /* 持久化对象 */
        manager.persist(insertedJpaStudent);
        /* 提交事务 */
        transaction.commit();
        /* 关闭 EntityManager */
        manager.close();
    }

    /**
     * 测试查询表中的所有学生
     * 1) 通过 createEntityManager() 方法获取一个 EntityManager 对象
     * 2) 通过 Query createQuery(String qlString) 方法进行查询
     * 3) 通过 getResultList() 方法获取查询到的列表
     * 4) 通过 close() 关闭 EntityManager
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testSelect() {
        /* 获取一个 EntityManager 对象 */
        EntityManager manager = factory.createEntityManager();
        /* 通过 HQL 查询所有学生 */
        Query query = manager.createQuery("from JpaStudent");
        /* 通过 getResultList() 获取查询到的学生列表 */
        List<JpaStudent> resultList = (List<JpaStudent>) query.getResultList();
        /* 输出查询到的数据 */
        for (JpaStudent jpaStudent : resultList) {
            System.out.println(jpaStudent);
        }
        /* 关闭 EntityManager */
        manager.close();
    }

    /**
     * 测试修改学生表的学生记录
     * 1) 通过 createEntityManager() 方法获取一个 EntityManager 对象
     * 2) 通过 find(Class<T> entityClass, Object primaryKey) 方法从数据库中查询出需要修改的学生
     * 3) 修改上一步查询出的实例
     * 4) 通过 getTransaction() 获取 EntityTransaction 对象控制事务
     * 5) 通过 begin() 方法开启事务
     * 6) 通过 persist(Object object) 持久化学生对象
     * 7) 通过 commit() 提交事务
     * 8) 通过 close() 关闭 EntityManager
     */
    @Test
    public void testUpdate() {
        /* 获取一个 EntityManager 对象 */
        EntityManager manager = factory.createEntityManager();
        /* 从数据库中查询出需要修改的记录，之所以这么做是因为修改是修改所有字段，因此未修改字段必须是原来的初始值 */
        JpaStudent jpaStudent = manager.find(JpaStudent.class, 7);
        /* 在查询到的原学生实例上进行修改 */
        jpaStudent.setAge(15);
        /* 获取 EntityTransaction 对象控制事务 */
        EntityTransaction transaction = manager.getTransaction();
        /* 开启事务 */
        transaction.begin();
        /* 更新对象 */
        manager.merge(jpaStudent);
        /* 提交事务 */
        transaction.commit();
        /* 关闭 EntityManager */
        manager.close();
    }

    /**
     * 测试删除学生表中的记录
     * 1) 通过 createEntityManager() 方法获取一个 EntityManager 对象
     * 2) 通过 find(Class<T> entityClass, Object primaryKey) 方法从数据库中查询出需要删除的学生
     * 3) 通过 getTransaction() 获取 EntityTransaction 对象控制事务
     * 4) 通过 begin() 方法开启事务
     * 5) 通过 remove(Object entity) 删除该学生记录
     * 6) 通过 commit() 提交事务
     * 7) 通过 close() 关闭 EntityManager
     */
    @Test
    public void testDelete() {
        /* 获取一个 EntityManager 对象 */
        EntityManager manager = factory.createEntityManager();
        /* 获取 EntityTransaction 对象控制事务 */
        EntityTransaction transaction = manager.getTransaction();
        /* 开启事务 */
        transaction.begin();
        /* 通过主键字段查询出需要删除记录 */
        JpaStudent jpaStudent = manager.find(JpaStudent.class, 7);
        /* 通过 remove(Object entity) 删除记录 */
        manager.remove(jpaStudent);
        /* 提交事务 */
        transaction.commit();
        /* 关闭 EntityManager */
        manager.close();
    }

}
